#include<iostream>
#include<cstring>
using namespace std;
const int N = 2e3 + 10, M = 3e3 + 10;
int n, m,pos;
struct node
{
	int u, v, w;
}a[M*2];//注意bf算法可以不建图
//因为有可能双向所以说空间这里成二
int dist[N];
bool bf()
{
	memset(dist, 0x3f, sizeof dist);
	dist[1] = 0;

	bool flag = false;
	for (int i = 1;i <= n;i++)//如果判断负边需要多走一次
	{
		flag = false;

		for (int j = 1;j <= pos;j++)
		{
			int u = a[j].u;int v = a[j].v;int w = a[j].w;

			if (dist[u] == 0x3f3f3f3f) continue;//如果这个点是无穷的话那他肯定更新不了，直接继续
			if (dist[u] + w < dist[v])
			{
				dist[v] = dist[u] + w;
				flag = true;
			}
		}
		if (flag == false) return false;//如果根本没更改说明已经ok了，没有副边
	}
	return true;
}
int main()
{
	int T = 0;
	cin >> T;
	while (T--)
	{
		cin >> n >> m;
		pos = 0;//清空
		for (int i = 1;i <= m;i++)
		{
			int u = 0, v = 0, w = 0;
			cin >> u >> v >> w;
			pos++;
			a[pos].u = u;a[pos].v = v;a[pos].w = w;
			if (w >= 0)
			{
				pos++;
				a[pos].u = v;a[pos].v = u;a[pos].w = w;
				//dj和bf算法都可以处理无向图，我们可以把无向图的每个边看成两个相反方向的边
				//dj不能处理负边问题
			}
		}
		if (bf()) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	
	return 0;
}